//---------------------------------------------------------
//  module:  Forwarding_Unit
//  File:  Forwarding_Unit.v
//  Created by:  Mitchell Kline
//  Purpose:  Forwards Correct Output from ALU
//---------------------------------------------------------

module Forwarding_Unit(
  ALUSrcSelect1, 
  ALUSrcSelect2,
  SWSrcSel,
  Rs,
  Rt,
  EXMEMRd,
  MEMWBRd,
  RegWrite,
  MemtoReg,
  RegDest
);

output [1:0] ALUSrcSelect1, ALUSrcSelect2, SWSrcSel;
input [4:0] Rs, Rt, EXMEMRd, MEMWBRd;
input RegWrite, MemtoReg, RegDest;

reg [1:0] ALUSrcSelect1, ALUSrcSelect2, SWSrcSel;

always @ (Rs or Rt or EXMEMRd or MEMWBRd or RegWrite or MemtoReg) begin

  case (Rs)
    EXMEMRd:  if (RegWrite) ALUSrcSelect1 = 2'd2;
              else ALUSrcSelect1 = 2'd0;
    MEMWBRd:  if (MemtoReg) ALUSrcSelect1 = 2'd1;
              else ALUSrcSelect1 = 2'd0;
    default:  ALUSrcSelect1 = 2'd0;
  endcase

  case (Rt)
    EXMEMRd:  begin 
              SWSrcSel = 2'd2;
              if (!RegDest) ALUSrcSelect2 = 2'd0;  // for immediate type instructions
              else if (RegWrite) ALUSrcSelect2 = 2'd2;
              else ALUSrcSelect2 = 2'd0;
    end
    MEMWBRd:  begin
              SWSrcSel = 2'd1;
              if (!RegDest) ALUSrcSelect2 = 2'd0;
              else if (MemtoReg) ALUSrcSelect2 = 2'd1;
              else ALUSrcSelect2 = 2'd0;
              end

    default:  begin ALUSrcSelect2 = 2'd0;  SWSrcSel = 2'd0; end
  endcase

end

endmodule
